home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / wmesa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-20  |  23.8 KB  |  960 lines

  1. /* wmesa.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * Windows driver by: Mark E. Peterson (markp@ic.mankato.mn.us)
  23.  */
  24.  
  25. /*
  26. $Id: wmesa.c,v 1.10 1995/11/20 20:11:08 brianp Exp $
  27.  
  28. $Log: wmesa.c,v $
  29.  * Revision 1.10  1995/11/20  20:11:08  brianp
  30.  * incorporated Mark's November 17th updates
  31.  *
  32.  * Revision 1.9  1995/10/30  15:30:00  brianp
  33.  * pass mask array to read_[index|color]_pixels()
  34.  *
  35.  * Revision 1.8  1995/10/19  15:44:42  brianp
  36.  * updated arguments to set_color, clear_color and gl_new_context
  37.  *
  38.  * Revision 1.7  1995/10/17  21:28:01  brianp
  39.  * updated for new device driver structure in Mesa 1.2.4
  40.  *
  41.  * Revision 1.6  1995/09/15  18:52:55  brianp
  42.  * cleaned up some code
  43.  * modified write_color_span to take NULL mask
  44.  *
  45.  * Revision 1.5  1995/07/24  18:56:00  brianp
  46.  * added dd_finish()
  47.  *
  48.  * Revision 1.4  1995/06/21  15:39:26  brianp
  49.  * removed #include "wmesaP.h"
  50.  *
  51.  * Revision 1.3  1995/06/21  15:38:10  brianp
  52.  * added struct_wmesa_context, don't need wmesaP.h anymore
  53.  *
  54.  * Revision 1.2  1995/06/09  18:53:39  brianp
  55.  * removed compute_mult_and_shift()
  56.  * dd_read/write_color_span/pixels() take GLubyte arrays instead of GLints
  57.  *
  58.  * Revision 1.1  1995/06/09  18:52:29  brianp
  59.  * Initial revision
  60.  *
  61.  */
  62.  
  63.  
  64. #include <stdlib.h>
  65. #include <windows.h>
  66. #include "gl\wmesa.h"
  67. #include "context.h"
  68. #include "dd.h"
  69. #include "xform.h"
  70. #include "vb.h"
  71. #include "wing.h"
  72.  
  73.  
  74. /* Bit's used for dest: */
  75. #define FRONT_PIXMAP    1
  76. #define BACK_PIXMAP    2
  77. #define BACK_XIMAGE    4
  78.  
  79. struct wmesa_context
  80. {
  81.   struct gl_context *gl_ctx;    /* the main library context */
  82.   HWND Window;
  83.   HDC Compat_DC;                /* Display context for double buffering. */
  84.   HBITMAP Old_Compat_BM,Compat_BM;            /* Bitmap for double buffering */
  85.   GLuint width, height,ScanWidth;
  86.   GLboolean db_flag;    /* double buffered? */
  87.   GLboolean rgb_flag;    /* RGB mode? */
  88.   GLuint depth;        /* bits per pixel (1, 8, 24, etc) */
  89.   unsigned long pixel;    /* current color index or RGBA pixel value */
  90.   unsigned long clearpixel; /* pixel for clearing the color buffers */
  91.   char *ScreenMem; // WinG memory
  92.   BITMAPINFO *IndexFormat;
  93.   HPALETTE hPal; // Current Palette
  94. };
  95.  
  96.  
  97. #ifdef NDEBUG
  98.   #define assert(ignore)    ((void) 0)
  99. #else
  100.   void Mesa_Assert(void *Cond,void *File,unsigned Line)
  101.   {
  102.     char Msg[512];
  103.     sprintf(Msg,"%s %s %d",Cond,File,Line);
  104.     MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
  105.     exit(1);
  106.   }
  107.   #define assert(e)    if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
  108. #endif
  109. #define DD_GETDC ((Current->db_flag) ? Current->Compat_DC : GetDC(Current->Window))
  110. #define DD_RELEASEDC if (!Current->db_flag) ReleaseDC(Current->Window,DC)
  111. static WMesaContext Current = NULL;
  112. #ifdef __SYMANTEC_BUGS
  113.   struct dd_function_table DD;
  114. #endif
  115. #define FLIP(Y)  (Current->height-(Y)-1)
  116.  
  117.  
  118.  
  119.  
  120.  
  121. /* Finish all pending operations and synchronize. */
  122. static void finish(void)
  123. {
  124.    /* no op */
  125. }
  126.  
  127.  
  128.  
  129. static void flush(void)
  130. {
  131.    /* no op */
  132. }
  133.  
  134.  
  135.  
  136. /*
  137.  * Set the color index used to clear the color buffer.
  138.  */
  139. static void clear_index(GLuint index)
  140. {
  141.   Current->clearpixel = index;
  142. }
  143.  
  144.  
  145.  
  146. /*
  147.  * Set the color used to clear the color buffer.
  148.  */
  149. static void clear_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  150. {
  151.   Current->clearpixel=RGB(r, g, b );
  152. }
  153.  
  154.  
  155.  
  156. /*
  157.  * Clear the specified region of the color buffer using the clear color
  158.  * or index as specified by one of the two functions above.
  159.  */
  160. static void clear(GLboolean all,GLint x, GLint y, GLint width, GLint height )
  161. {
  162.   if (all)
  163.   {
  164.     x=y=0;
  165.     width=Current->width;
  166.     height=Current->height;
  167.   }
  168.   if (Current->rgb_flag==GL_TRUE)
  169.   {
  170.     HDC DC=DD_GETDC;
  171.     HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
  172.     HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
  173.     HPEN Old_Pen=SelectObject(DC,Pen);
  174.     HBRUSH Old_Brush=SelectObject(DC,Brush);
  175.     Rectangle(DC,x,y,x+width,y+height);
  176.     SelectObject(DC,Old_Pen);
  177.     SelectObject(DC,Old_Brush);
  178.     DeleteObject(Pen);
  179.     DeleteObject(Brush);
  180.     DD_RELEASEDC;
  181.   }
  182.   else
  183.   {
  184.     int i;
  185.     char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  186.     for (i=0; i<height; i++)
  187.     {
  188.       memset(Mem,Current->clearpixel,width);
  189.       Mem+=width;
  190.     }
  191.   }
  192. }
  193.  
  194.  
  195.  
  196. /* Set the current color index. */
  197. static void set_index(GLuint index)
  198. {
  199.   Current->pixel=index;
  200. }
  201.  
  202.  
  203.  
  204. /* Set the current RGBA color. */
  205. static void set_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  206. {
  207.   Current->pixel = RGB( r, g, b );
  208. }
  209.  
  210.  
  211.  
  212. /* Set the index mode bitplane mask. */
  213. static GLboolean index_mask(GLuint mask)
  214. {
  215.    /* can't implement */
  216.    return GL_FALSE;
  217. }
  218.  
  219.  
  220.  
  221. /* Set the RGBA drawing mask. */
  222. static GLboolean color_mask( GLboolean rmask, GLboolean gmask,
  223.                              GLboolean bmask, GLboolean amask)
  224. {
  225.    /* can't implement */
  226.    return GL_FALSE;
  227. }
  228.  
  229.  
  230.  
  231. /*
  232.  * Set the pixel logic operation.  Return GL_TRUE if the device driver
  233.  * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  234.  * is returned, the logic op will be done in software by Mesa.
  235.  */
  236. GLboolean logicop( GLenum op )
  237. {
  238.    /* can't implement */
  239.    return GL_FALSE;
  240. }
  241.  
  242.  
  243. static void dither( GLboolean enable )
  244. {
  245.    /* No op */
  246. }
  247.  
  248.  
  249.  
  250. static GLboolean set_buffer( GLenum mode )
  251. {
  252.    /* TODO: this could be better */
  253.    if (mode==GL_FRONT || mode==GL_BACK) {
  254.       return GL_TRUE;
  255.    }
  256.    else {
  257.       return GL_FALSE;
  258.    }
  259. }
  260.  
  261.  
  262.  
  263. /* Return characteristics of the output buffer. */
  264. static void buffer_size( GLuint *width, GLuint *height, GLuint *depth )
  265. {
  266.   int New_Size;
  267.   RECT CR;
  268.   GetClientRect(Current->Window,&CR);
  269.   *width=CR.right;
  270.   *height=CR.bottom;
  271.   *depth = Current->depth;
  272.   New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
  273.   if (New_Size)
  274.   {
  275.     Current->width=*width;
  276.     Current->ScanWidth=Current->width;
  277.     if ((Current->ScanWidth%sizeof(long))!=0)
  278.       Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
  279.     Current->height=*height;
  280.     if (Current->db_flag)
  281.     {
  282.       if (Current->rgb_flag==GL_TRUE)
  283.         Current->Compat_BM=CreateCompatibleBitmap(Current->Compat_DC,Current->width,Current->height);
  284.       else
  285.       {
  286.         Current->IndexFormat->bmiHeader.biWidth=Current->width;
  287.         if (Current->IndexFormat->bmiHeader.biHeight<0)
  288.           Current->IndexFormat->bmiHeader.biHeight=-Current->height;
  289.         else
  290.           Current->IndexFormat->bmiHeader.biHeight=Current->height;
  291.         Current->Compat_BM=WinGCreateBitmap(Current->Compat_DC,Current->IndexFormat,&((void *) Current->ScreenMem));
  292.       }
  293.       DeleteObject(SelectObject(Current->Compat_DC,Current->Compat_BM));
  294.     }
  295.   }
  296. }
  297.  
  298.  
  299.  
  300. /**********************************************************************/
  301. /*****           Accelerated point, line, polygon rendering       *****/
  302. /**********************************************************************/
  303.  
  304.  
  305. static void fast_rgb_points( GLuint first, GLuint last )
  306. {
  307.    int i;
  308.    HDC DC=DD_GETDC;
  309.    if (VB.MonoColor) {
  310.       /* all drawn with current color */
  311.       for (i=first;i<=last;i++) {
  312.          if (VB.Unclipped[i]) {
  313.             int x, y;
  314.             x =       (GLint) (VB.Win[i][0] + 0.05F);
  315.             y = FLIP( (GLint) (VB.Win[i][1] + 0.05F) );
  316.             SetPixel(DC,x,y,Current->pixel);
  317.          }
  318.       }
  319.    }
  320.    else {
  321.       /* draw points of different colors */
  322.       HPEN Pen=CreatePen(PS_SOLID,1,Current->pixel);
  323.       HPEN Old_Pen=SelectObject(DC,Pen);
  324.       for (i=first;i<=last;i++) {
  325.          if (VB.Unclipped[i]) {
  326.             int x, y;
  327.             unsigned long pixel=RGB(VB.Color[i][0]*255.0,
  328.                                     VB.Color[i][1]*255.0,
  329.                                     VB.Color[i][2]*255.0);
  330.             x =       (GLint) (VB.Win[i][0] + 0.05F);
  331.             y = FLIP( (GLint) (VB.Win[i][1] + 0.05F) );
  332.             SetPixel(DC,x,y,pixel);
  333.          }
  334.       }
  335.       SelectObject(DC,Old_Pen);
  336.       DeleteObject(Pen);
  337.    }
  338.    DD_RELEASEDC;
  339. }
  340.  
  341.  
  342.  
  343. /* Return pointer to accerated points function */
  344. static points_func choose_points_function( void )
  345. {
  346.    if (CC.Point.Size==1.0 && !CC.Point.SmoothFlag && CC.RasterMask==0
  347.        && !CC.Texture.Enabled  && Current->rgb_flag) {
  348.       return fast_rgb_points;
  349.    }
  350.    else {
  351.       return NULL;
  352.    }
  353. }
  354.  
  355.  
  356.  
  357. /* Draw a line using the color specified by VB.Color[pv] */
  358. static void fast_flat_rgb_line( GLuint v0, GLuint v1, GLuint pv )
  359. {
  360.    int x0, y0, x1, y1;
  361.    unsigned long pixel;
  362.    HDC DC=DD_GETDC;
  363.    HPEN Pen;
  364.    HPEN Old_Pen;
  365.  
  366.    if (VB.MonoColor) {
  367.       pixel = Current->pixel;  /* use current color */
  368.    }
  369.    else {
  370.       pixel = RGB(VB.Color[pv][0]*255.0, VB.Color[pv][1]*255.0, VB.Color[pv][2]*255.0);
  371.    }
  372.  
  373.    x0 =       (int) (VB.Win[v0][0] + 0.05F);
  374.    y0 = FLIP( (int) (VB.Win[v0][1] + 0.05F) );
  375.    x1 =       (int) (VB.Win[v1][0] + 0.05F);
  376.    y1 = FLIP( (int) (VB.Win[v1][1] + 0.05F) );
  377.  
  378.    Pen=CreatePen(PS_SOLID,1,pixel);
  379.    Old_Pen=SelectObject(DC,Pen);
  380.    MoveToEx(DC,x0,y0,NULL);
  381.    LineTo(DC,x1,y1);
  382.    SelectObject(DC,Old_Pen);
  383.    DeleteObject(Pen);
  384.    DD_RELEASEDC;
  385. }
  386.  
  387.  
  388.  
  389. /* Return pointer to accerated line function */
  390. static line_func choose_line_function( void )
  391. {
  392.    if (CC.Line.Width==1.0 && !CC.Line.SmoothFlag && !CC.Line.StippleFlag
  393.        && CC.Light.ShadeModel==GL_FLAT && CC.RasterMask==0
  394.        && !CC.Texture.Enabled && Current->rgb_flag) {
  395.       return fast_flat_rgb_line;
  396.    }
  397.    else {
  398.       return NULL;
  399.    }
  400. }
  401.  
  402.  
  403. /* Draw a convex polygon using color VB.Color[pv] */
  404. static void fast_flat_rgb_polygon( GLuint n, GLuint vlist[], GLuint pv )
  405. {
  406.    POINT *Pts=(POINT *) malloc(n*sizeof(POINT));
  407.    HDC DC=DD_GETDC;
  408.    HPEN Pen;
  409.    HBRUSH Brush;
  410.    HPEN Old_Pen;
  411.    HBRUSH Old_Brush;
  412.    GLint pixel;
  413.    int i;
  414.  
  415.    if (VB.MonoColor) {
  416.       pixel = Current->pixel;  /* use current color */
  417.    }
  418.    else {
  419.       pixel = RGB(VB.Color[pv][0]*255.0, VB.Color[pv][1]*255.0, VB.Color[pv][2]*255.0);
  420.    }
  421.  
  422.    Pen=CreatePen(PS_SOLID,1,pixel);
  423.    Brush=CreateSolidBrush(pixel);
  424.    Old_Pen=SelectObject(DC,Pen);
  425.    Old_Brush=SelectObject(DC,Brush);
  426.  
  427.    for (i=0; i<n; i++) {
  428.       int j = vlist[i];
  429.       Pts[i].x =       (int) (VB.Win[j][0] + 0.5F);
  430.       Pts[i].y = FLIP( (int) (VB.Win[j][1] + 0.5F) );
  431.    }
  432.    Polygon(DC,Pts,n);
  433.    SelectObject(DC,Old_Pen);
  434.    SelectObject(DC,Old_Brush);
  435.    DeleteObject(Pen);
  436.    DeleteObject(Brush);
  437.    DD_RELEASEDC;
  438.    free(Pts);
  439. }
  440.  
  441.  
  442.  
  443. /* Return pointer to accerated polygon function */
  444. static polygon_func choose_polygon_function( void )
  445. {
  446.    if (!CC.Polygon.SmoothFlag && !CC.Polygon.StippleFlag
  447.        && CC.Light.ShadeModel==GL_FLAT && CC.RasterMask==0
  448.        && !CC.Texture.Enabled && Current->rgb_flag==GL_TRUE) {
  449.       return fast_flat_rgb_polygon;
  450.    }
  451.    else {
  452.       return NULL;
  453.    }
  454. }
  455.  
  456.  
  457.  
  458. /**********************************************************************/
  459. /*****                 Span-based pixel drawing                   *****/
  460. /**********************************************************************/
  461.  
  462.  
  463. /* Write a horizontal span of color-index pixels with a boolean mask. */
  464. static void write_index_span( GLuint n, GLint x, GLint y,
  465.                               const GLuint index[],
  466.                               const GLubyte mask[] )
  467. {
  468.   int i;
  469.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  470.   assert(Current->rgb_flag==GL_FALSE);
  471.   for (i=0; i<n; i++)
  472.     if (mask[i])
  473.       Mem[i]=index[i];
  474. }
  475.  
  476.  
  477.  
  478. /*
  479.  * Write a horizontal span of pixels with a boolean mask.  The current
  480.  * color index is used for all pixels.
  481.  */
  482. static void write_monoindex_span(GLuint n,GLint x,GLint y,const GLubyte mask[])
  483. {
  484.   int i;
  485.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  486.   assert(Current->rgb_flag==GL_FALSE);
  487.   for (i=0; i<n; i++)
  488.     if (mask[i])
  489.       Mem[i]=Current->pixel;
  490. }
  491.  
  492.  
  493.  
  494. /* Write a horizontal span of color pixels with a boolean mask. */
  495. static void write_color_span( GLuint n, GLint x, GLint y,
  496.               const GLubyte red[], const GLubyte green[],
  497.               const GLubyte blue[], const GLubyte alpha[],
  498.               const GLubyte mask[] )
  499. {
  500.   if (Current->rgb_flag==GL_TRUE)
  501.   {
  502.     int i;
  503.     HDC DC=DD_GETDC;
  504.     y=FLIP(y);
  505.     if (mask) {
  506.        for (i=0; i<n; i++)
  507.          if (mask[i])
  508.            SetPixel(DC,x+i,y,RGB(red[i],green[i],blue[i]));
  509.     }
  510.     else {
  511.        for (i=0; i<n; i++)
  512.          SetPixel(DC,x+i,y,RGB(red[i],green[i],blue[i]));
  513.     }
  514.     DD_RELEASEDC;
  515.   }
  516.   else
  517.   {
  518.     int i;
  519.     char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  520.     if (mask) {
  521.        for (i=0; i<n; i++)
  522.          if (mask[i])
  523.            Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  524.     }
  525.     else {
  526.        for (i=0; i<n; i++)
  527.          Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  528.     }
  529.   }
  530. }
  531.  
  532.  
  533.  
  534. /*
  535.  * Write a horizontal span of pixels with a boolean mask.  The current color
  536.  * is used for all pixels.
  537.  */
  538. static void write_monocolor_span( GLuint n, GLint x, GLint y,const GLubyte mask[])
  539. {
  540.   int i;
  541.   HDC DC=DD_GETDC;
  542.   assert(Current->rgb_flag==GL_TRUE);
  543.   y=FLIP(y);
  544.   for (i=0; i<n; i++)
  545.     if (mask[i])
  546.       SetPixel(DC,x+i,y,Current->pixel);
  547.   DD_RELEASEDC;
  548. }
  549.  
  550.  
  551.  
  552. /**********************************************************************/
  553. /*****                   Array-based pixel drawing                *****/
  554. /**********************************************************************/
  555.  
  556.  
  557. /* Write an array of pixels with a boolean mask. */
  558. static void write_index_pixels( GLuint n, const GLint x[], const GLint y[],
  559.                                 const GLuint index[], const GLubyte mask[] )
  560. {
  561.    int i;
  562.    assert(Current->rgb_flag==GL_FALSE);
  563.    for (i=0; i<n; i++) {
  564.       if (mask[i]) {
  565.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  566.          *Mem = index[i];
  567.       }
  568.    }
  569. }
  570.  
  571.  
  572.  
  573. /*
  574.  * Write an array of pixels with a boolean mask.  The current color
  575.  * index is used for all pixels.
  576.  */
  577. static void write_monoindex_pixels( GLuint n,
  578.                                     const GLint x[], const GLint y[],
  579.                                     const GLubyte mask[] )
  580. {
  581.    int i;
  582.    assert(Current->rgb_flag==GL_FALSE);
  583.    for (i=0; i<n; i++) {
  584.       if (mask[i]) {
  585.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  586.          *Mem = Current->pixel;
  587.       }
  588.    }
  589. }
  590.  
  591.  
  592.  
  593. /* Write an array of pixels with a boolean mask. */
  594. static void write_color_pixels( GLuint n, const GLint x[], const GLint y[],
  595.                                 const GLubyte r[], const GLubyte g[],
  596.                                 const GLubyte b[], const GLubyte a[],
  597.                                 const GLubyte mask[] )
  598. {
  599.   int i;
  600.   HDC DC=DD_GETDC;
  601.   assert(Current->rgb_flag==GL_TRUE);
  602.   for (i=0; i<n; i++)
  603.     if (mask[i])
  604.       SetPixel(DC,x[i],FLIP(y[i]),RGB(r[i],g[i],b[i]));
  605.   DD_RELEASEDC;
  606. }
  607.  
  608.  
  609.  
  610. /*
  611.  * Write an array of pixels with a boolean mask.  The current color
  612.  * is used for all pixels.
  613.  */
  614. static void write_monocolor_pixels( GLuint n,
  615.                                     const GLint x[], const GLint y[],
  616.                                     const GLubyte mask[] )
  617. {
  618.   int i;
  619.   HDC DC=DD_GETDC;
  620.   assert(Current->rgb_flag==GL_TRUE);
  621.   for (i=0; i<n; i++)
  622.     if (mask[i])
  623.       SetPixel(DC,x[i],FLIP(y[i]),Current->pixel);
  624.   DD_RELEASEDC;
  625. }
  626.  
  627.  
  628.  
  629. /**********************************************************************/
  630. /*****            Read spans/arrays of pixels                     *****/
  631. /**********************************************************************/
  632.  
  633.  
  634. /* Read a horizontal span of color-index pixels. */
  635. static void read_index_span( GLuint n, GLint x, GLint y, GLuint index[])
  636. {
  637.   int i;
  638.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  639.   assert(Current->rgb_flag==GL_FALSE);
  640.   for (i=0; i<n; i++)
  641.     index[i]=Mem[i];
  642. }
  643.  
  644.  
  645.  
  646.  
  647. /* Read an array of color index pixels. */
  648. static void read_index_pixels( GLuint n, const GLint x[], const GLint y[],
  649.                                GLuint indx[], const GLubyte mask[] )
  650. {
  651.   int i;
  652.   assert(Current->rgb_flag==GL_FALSE);
  653.   for (i=0; i<n; i++) {
  654.      if (mask[i]) {
  655.         indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);
  656.      }
  657.   }
  658. }
  659.  
  660.  
  661.  
  662. /* Read a horizontal span of color pixels. */
  663. static void read_color_span( GLuint n, GLint x, GLint y,
  664.                              GLubyte red[], GLubyte green[],
  665.                              GLubyte blue[], GLubyte alpha[] )
  666. {
  667.   int i;
  668.   COLORREF Color;
  669.   HDC DC=DD_GETDC;
  670.   assert(Current->rgb_flag==GL_TRUE);
  671.   y=FLIP(y);
  672.   for (i=0; i<n; i++)
  673.   {
  674.     Color=GetPixel(DC,x+i,y);
  675.     red[i]=GetRValue(Color);
  676.     green[i]=GetGValue(Color);
  677.     blue[i]=GetBValue(Color);
  678.     alpha[i]=255;
  679.   }
  680.   DD_RELEASEDC;
  681.   memset(alpha,0,n*sizeof(GLint));
  682. }
  683.  
  684.  
  685. /* Read an array of color pixels. */
  686. static void read_color_pixels( GLuint n, const GLint x[], const GLint y[],
  687.                                GLubyte red[], GLubyte green[],
  688.                                GLubyte blue[], GLubyte alpha[],
  689.                                const GLubyte mask[] )
  690. {
  691.   int i;
  692.   COLORREF Color;
  693.   HDC DC=DD_GETDC;
  694.   assert(Current->rgb_flag==GL_TRUE);
  695.   for (i=0; i<n; i++) {
  696.      if (mask[i]) {
  697.         Color=GetPixel(DC,x[i],FLIP(y[i]));
  698.         red[i]=GetRValue(Color);
  699.         green[i]=GetGValue(Color);
  700.         blue[i]=GetBValue(Color);
  701.         alpha[i]=255;
  702.      }
  703.   }
  704.   DD_RELEASEDC;
  705.   memset(alpha,0,n*sizeof(GLint));
  706. }
  707.  
  708.  
  709.  
  710. /**********************************************************************/
  711. /**********************************************************************/
  712.  
  713.  
  714.  
  715. static void setup_DD_pointers( void )
  716. {
  717.    DD.finish = finish;
  718.    DD.flush = flush;
  719.  
  720.    DD.clear_index = clear_index;
  721.    DD.clear_color = clear_color;
  722.    DD.clear = clear;
  723.  
  724.    DD.index = set_index;
  725.    DD.color = set_color;
  726.    DD.index_mask = index_mask;
  727.    DD.color_mask = color_mask;
  728.  
  729.    DD.logicop = logicop;
  730.    DD.dither = dither;
  731.  
  732.    DD.set_buffer = set_buffer;
  733.    DD.buffer_size = buffer_size;
  734.  
  735.    DD.get_points_func = choose_points_function;
  736.    DD.get_line_func = choose_line_function;
  737.    DD.get_polygon_func = choose_polygon_function;
  738.  
  739.    /* Pixel/span writing functions: */
  740.    DD.write_color_span       = write_color_span;
  741.    DD.write_monocolor_span   = write_monocolor_span;
  742.    DD.write_color_pixels     = write_color_pixels;
  743.    DD.write_monocolor_pixels = write_monocolor_pixels;
  744.    DD.write_index_span       = write_index_span;
  745.    DD.write_monoindex_span   = write_monoindex_span;
  746.    DD.write_index_pixels     = write_index_pixels;
  747.    DD.write_monoindex_pixels = write_monoindex_pixels;
  748.  
  749.    /* Pixel/span reading functions: */
  750.    DD.read_index_span = read_index_span;
  751.    DD.read_color_span = read_color_span;
  752.    DD.read_index_pixels = read_index_pixels;
  753.    DD.read_color_pixels = read_color_pixels;
  754. }
  755.  
  756.  
  757.  
  758. /**********************************************************************/
  759. /*****                  WMesa API Functions                       *****/
  760. /**********************************************************************/
  761.  
  762.  
  763.  
  764. #define PAL_SIZE 256
  765. static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
  766. {
  767.     int i;
  768.     HDC hdc;
  769.     struct
  770.     {
  771.         WORD Version;
  772.         WORD NumberOfEntries;
  773.         PALETTEENTRY aEntries[PAL_SIZE];
  774.     } Palette =
  775.     {
  776.         0x300,
  777.         PAL_SIZE
  778.     };
  779.     hdc=GetDC(NULL);
  780.     if (Pal!=NULL)
  781.     GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
  782.   else
  783.     GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
  784.     if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
  785.     {
  786.         for(i = 0; i <PAL_SIZE; i++)
  787.             Palette.aEntries[i].peFlags = PC_RESERVED;
  788.         Palette.aEntries[255].peRed = 255;
  789.         Palette.aEntries[255].peGreen = 255;
  790.         Palette.aEntries[255].peBlue = 255;
  791.         Palette.aEntries[255].peFlags = 0;
  792.         Palette.aEntries[0].peRed = 0;
  793.         Palette.aEntries[0].peGreen = 0;
  794.         Palette.aEntries[0].peBlue = 0;
  795.         Palette.aEntries[0].peFlags = 0;
  796.     }
  797.     else
  798.     {
  799.         int nStaticColors;
  800.         int nUsableColors;
  801.         nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
  802.         for (i=0; i<nStaticColors; i++)
  803.             Palette.aEntries[i].peFlags = 0;
  804.         nUsableColors = PAL_SIZE-nStaticColors;
  805.         for (; i<nUsableColors; i++)
  806.             Palette.aEntries[i].peFlags = PC_RESERVED;
  807.         for (; i<PAL_SIZE-nStaticColors; i++)
  808.             Palette.aEntries[i].peFlags = PC_RESERVED;
  809.         for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
  810.             Palette.aEntries[i].peFlags = 0;
  811.     }
  812.     ReleaseDC(NULL,hdc);
  813.   for (i=0; i<PAL_SIZE; i++)
  814.   {
  815.     aRGB[i].rgbRed=Palette.aEntries[i].peRed;
  816.     aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
  817.     aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
  818.     aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
  819.   }
  820. }
  821.  
  822.  
  823.  
  824. WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE Pal, GLboolean rgb_flag,
  825.                                  GLboolean db_flag )
  826. {
  827.   BITMAPINFO *Rec;
  828.   HDC DC;
  829.   RECT CR;
  830.   WMesaContext c;
  831.  
  832.   c = (struct wmesa_context *) calloc(1,sizeof(struct wmesa_context));
  833.   if (!c)
  834.     return NULL;
  835.  
  836.   c->Window=hWnd;
  837.   if (rgb_flag==GL_FALSE)
  838.   {
  839.     c->rgb_flag = GL_FALSE;
  840.     c->pixel = 1;
  841.     db_flag=GL_TRUE; // WinG requires double buffering
  842.     //c->gl_ctx->BufferDepth = windepth;
  843.   }
  844.   else
  845.   {
  846.     c->rgb_flag = GL_TRUE;
  847.     c->pixel = 0;
  848.   }
  849.   GetClientRect(c->Window,&CR);
  850.   c->width=CR.right;
  851.   c->height=CR.bottom;
  852.   if (db_flag)
  853.   {
  854.     c->db_flag = 1;
  855.     /* Double buffered */
  856.     if (c->rgb_flag==GL_TRUE)
  857.     {
  858.       DC=GetDC(c->Window);
  859.       c->Compat_DC=CreateCompatibleDC(DC);
  860.       c->Compat_BM=CreateCompatibleBitmap(DC,c->width,c->height);
  861.       ReleaseDC(c->Window,DC);
  862.       c->Old_Compat_BM=SelectObject(c->Compat_DC,c->Compat_BM);
  863.     }
  864.     else
  865.     {
  866.       c->Compat_DC=WinGCreateDC();
  867.       Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));
  868.       c->hPal=Pal;
  869.       GetPalette(Pal,Rec->bmiColors);
  870.       WinGRecommendDIBFormat(Rec);
  871.       Rec->bmiHeader.biWidth=c->width;
  872.       Rec->bmiHeader.biHeight*=c->height;
  873.       Rec->bmiHeader.biClrUsed=PAL_SIZE;
  874.       if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)
  875.       {
  876.         MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);
  877.         exit(1);
  878.       }
  879.       c->Compat_BM=WinGCreateBitmap(c->Compat_DC,Rec,&((void *) c->ScreenMem));
  880.       c->Old_Compat_BM=SelectObject(c->Compat_DC,c->Compat_BM);
  881.       WinGSetDIBColorTable(c->Compat_DC,0,PAL_SIZE,Rec->bmiColors);
  882.       c->IndexFormat=Rec;
  883.       c->ScanWidth=c->width;
  884.       if ((c->ScanWidth%sizeof(long))!=0)
  885.         c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));
  886.     }
  887.   }
  888.   else
  889.   {
  890.     /* Single Buffered */
  891.     c->db_flag = 0;
  892.   }
  893.  
  894.   /* allocate a new Mesa context */
  895.   c->gl_ctx = gl_new_context( rgb_flag,
  896.                               255.0, 255.0, 255.0, 255.0,
  897.                               db_flag, NULL);
  898.  
  899.   setup_DD_pointers();
  900.  
  901.   return c;
  902. }
  903.  
  904.  
  905.  
  906. void WMesaDestroyContext( WMesaContext c )
  907. {
  908.    gl_destroy_context( c->gl_ctx );
  909.    if (c->db_flag)
  910.    {
  911.      SelectObject(c->Compat_DC,c->Old_Compat_BM);
  912.      DeleteDC(c->Compat_DC);
  913.      DeleteObject(c->Compat_BM);
  914.    }
  915.    free( (void *) c );
  916. }
  917.  
  918.  
  919.  
  920. void WMesaMakeCurrent( WMesaContext c )
  921. {
  922.    gl_set_context( c->gl_ctx );
  923.    Current = c;
  924.    setup_DD_pointers();
  925.    if (Current->gl_ctx->Viewport.Width==0) {
  926.       /* initialize viewport to window size */
  927.       gl_viewport( 0, 0, Current->width, Current->height );
  928.    }
  929. }
  930.  
  931.  
  932.  
  933. void WMesaSwapBuffers( void )
  934. {
  935.   // *** Perhaps the DC should be saved in WMesaContext?
  936.   HDC DC;
  937.   if (Current->db_flag)
  938.   {
  939.     DC=GetDC(Current->Window);
  940.     if (Current->rgb_flag)
  941.       BitBlt(DC,0,0,Current->width,Current->height,Current->Compat_DC,0,0,SRCCOPY);
  942.     else
  943.       WinGBitBlt(DC,0,0,Current->width,Current->height,Current->Compat_DC,0,0);
  944.     ReleaseDC(Current->Window,DC);
  945.   }
  946. }
  947.  
  948.  
  949.  
  950. void WMesaPaletteChange(HPALETTE Pal)
  951. {
  952.   if (Current && Current->rgb_flag==GL_FALSE)
  953.   {
  954.     Current->hPal=Pal;
  955.     GetPalette(Pal,Current->IndexFormat->bmiColors);
  956.     WinGSetDIBColorTable(Current->Compat_DC,0,PAL_SIZE,Current->IndexFormat->bmiColors);
  957.   }
  958. }
  959.  
  960.